#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
单线程补充缺失的历史最大风速数据脚本
从Visual Crossing API获取真实风速数据
"""

import sys
import requests
import logging
from pathlib import Path
from datetime import datetime, timedelta, date
from typing import List, Dict, Optional
import time
import os

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.absolute()
sys.path.insert(0, str(project_root))

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('single_thread_windspeed_fix.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

def get_visual_crossing_api_key():
    """获取Visual Crossing API密钥"""
    try:
        from backend.config.weather_config import WeatherConfig
        api_key = WeatherConfig.get_api_key()
        if api_key and api_key != 'YOUR_VISUAL_CROSSING_API_KEY':
            return api_key
        else:
            logger.error("Visual Crossing API密钥未正确配置")
            return None
    except ImportError:
        logger.error("无法导入WeatherConfig")
        return None

def get_weather_data_from_api(date_str: str, location: str = "Beijing,China") -> Optional[Dict]:
    """从Visual Crossing API获取指定日期的天气数据"""
    api_key = get_visual_crossing_api_key()
    if not api_key:
        return None
    
    try:
        url = f"https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/{location}/{date_str}/{date_str}"
        params = {
            'unitGroup': 'metric',
            'include': 'days',
            'key': api_key,
            'contentType': 'json'
        }
        
        response = requests.get(url, params=params, timeout=30)
        
        if response.status_code == 200:
            data = response.json()
            if 'days' in data and len(data['days']) > 0:
                return data['days'][0]
            else:
                logger.warning(f"API返回数据格式异常: {date_str}")
                return None
        elif response.status_code == 429:
            logger.error(f"API请求频率限制: {date_str}")
            return None
        else:
            logger.error(f"API请求失败: {response.status_code} - {response.text}")
            return None
            
    except Exception as e:
        logger.error(f"获取天气数据异常: {date_str} - {str(e)}")
        return None

def get_missing_windspeed_records_batch(batch_size=50):
    """分批获取缺失风速数据的记录"""
    try:
        from backend.config.database import get_db_session
        from backend.entities.weather_daily import WeatherDaily
        from sqlalchemy import and_
        
        db = get_db_session()
        missing_records = db.query(WeatherDaily).filter(
            and_(
                WeatherDaily.t_max.isnot(None),  # 有气象数据
                WeatherDaily.ws_max.is_(None)    # 但缺失风速
            )
        ).order_by(WeatherDaily.dt).limit(batch_size).all()
        
        db.close()
        return missing_records
    except Exception as e:
        logger.error(f"获取缺失记录失败: {str(e)}")
        return []

def update_windspeed_single_thread():
    """单线程更新风速数据"""
    try:
        from backend.config.database import get_db_session
        from backend.entities.weather_daily import WeatherDaily
        from sqlalchemy import and_
        
        updated_count = 0
        total_processed = 0
        
        while True:
            # 获取一批缺失风速数据的记录
            missing_records = get_missing_windspeed_records_batch(20)
            
            if not missing_records:
                logger.info("没有更多缺失风速数据的记录")
                break
            
            logger.info(f"开始处理 {len(missing_records)} 条记录...")
            
            # 为每个记录获取风速数据
            for record in missing_records:
                try:
                    date_str = record.dt.strftime('%Y-%m-%d')
                    
                    # 从API获取天气数据
                    weather_data = get_weather_data_from_api(date_str)
                    
                    if weather_data and 'windspeed' in weather_data:
                        windspeed = weather_data['windspeed']
                        
                        # 更新数据库记录
                        db = get_db_session()
                        try:
                            record_to_update = db.query(WeatherDaily).filter(
                                WeatherDaily.id == record.id
                            ).first()
                            
                            if record_to_update:
                                record_to_update.ws_max = windspeed
                                record_to_update.updated_at = datetime.now()
                                db.commit()
                                updated_count += 1
                                
                                logger.info(f"✅ 更新成功: {date_str} - 风速: {windspeed} km/h")
                            else:
                                logger.warning(f"记录不存在: {date_str}")
                                
                        except Exception as e:
                            db.rollback()
                            logger.error(f"数据库更新失败: {date_str} - {str(e)}")
                        finally:
                            db.close()
                    else:
                        logger.warning(f"无法获取风速数据: {date_str}")
                    
                    total_processed += 1
                    
                    # 添加延迟避免API频率限制
                    time.sleep(1)
                    
                except Exception as e:
                    logger.error(f"处理记录失败: {record.dt} - {str(e)}")
                    total_processed += 1
                    continue
            
            logger.info(f"批次完成 - 已处理: {total_processed}, 已更新: {updated_count}")
            
            # 检查是否还有更多记录
            remaining = get_missing_windspeed_records_batch(1)
            if not remaining:
                break
        
        logger.info(f"✅ 风速数据更新完成!")
        logger.info(f"总处理记录数: {total_processed}")
        logger.info(f"成功更新记录数: {updated_count}")
        
    except Exception as e:
        logger.error(f"更新风速数据失败: {str(e)}")

def main():
    """主函数"""
    logger.info("开始单线程风速数据补充...")
    
    # 测试API连接
    logger.info("测试API连接...")
    test_data = get_weather_data_from_api("2024-01-01")
    if test_data:
        logger.info("✅ API连接正常")
        logger.info(f"测试数据: {test_data.get('windspeed', 'N/A')} km/h")
    else:
        logger.error("❌ API连接失败")
        return
    
    # 开始更新风速数据
    update_windspeed_single_thread()

if __name__ == "__main__":
    main() 